#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dpglib.h>
#include "utils.h"

FILE* safe_open(char* filename)
{
	FILE* file = NULL;
	//try verify if file exist
	if (access(filename, R_OK) == -1)
	{
		fprintf(stderr, "error : file not exist or no permission to open it\n");
		return NULL;
	}

	//it's done : try to open 
	file = fopen(filename, "r");
	if (file == NULL)
	{
		fprintf(stderr, "error : can't open file, try again\n");
		return NULL;
	}
	
	return file;
	
}
DpgHeader read_header(char* filename)
{
	DpgHeader header;
	int i = 0;
	FILE* file = NULL;
	struct stat stat_file;

	if (filename == NULL)
	{
		header.error = BAD_ARGS;
		return header;
	}
	file = safe_open(filename);
	header.file = file;
	if (file == NULL)
	{
		if (access(filename, R_OK) == -1)
		{
			header.error = FILE_NOT_EXIST;
		}
		else
		{
			header.error = CANT_OPEN_FILE;
		}
		return header;
	}
	stat(filename, &stat_file);
	

	//step 1 : verifing if file is lower them 36 byte
	if (stat_file.st_size < 63)
	{
		header.error = FILE_TOO_SLOW;
		return header;
	}

	//done collect all header
	fread(&(header.raw_data), sizeof(uint8_t) ,36, file);

	//parse it
	//step 2 : identifing code
	if (memcmp(header.raw_data, "DPG0",  sizeof(uint8_t) * 4) != 0)
	{
		header.error = BAD_IDENT;
		return header;
	}
	//step 3 : collect number of frams
	i+=4;
	memcpy(&(header.nb_frames), &(header.raw_data[i]), sizeof(uint8_t) * 4);
	
	//step 4 : collect fps
	i+=4;
	memcpy(&(header.fps), &(header.raw_data[i]), sizeof(uint8_t) * 2);
	
	//step 5 : chech first check code
	i+=2;
	if (memcmp(&(header.raw_data[i]), "\0\0", sizeof(uint8_t) * 2) != 0)
	{
		header.error = BAD_CONTROL_1;
		return header;
	} 

	//step 6 : collect audio sample rate
	i+=2;
	memcpy(&(header.sample_rate), &(header.raw_data[i]), sizeof(uint8_t) * 4);

	//step 7 : check seccond check code
	i+=4;
	if (memcmp(&(header.raw_data[i]), "\0\0\0\0", sizeof(uint8_t) * 4) != 0)
	{
		header.error = BAD_CONTROL_2;
		return header;
	}

	//step 8 : collect bigin of audio file
	i+=4; 
	memcpy(&(header.bigin_audio_file), &(header.raw_data[i]), sizeof(uint8_t) * 4);

	//step 9 : collect len of audio file
	i+=4;
	memcpy(&(header.len_audio_file), &(header.raw_data[i]), sizeof(uint8_t) * 4);

	//step 10 : collect bigin of video file
	i+=4;
	memcpy(&(header.bigin_video_file), &(header.raw_data[i]), sizeof(uint8_t) * 4);
	
	//step 11 : collect len of video file
	i+=4;
	memcpy(&(header.len_video_file), &(header.raw_data[i]), sizeof(uint8_t) * 4);

	//step 12 : verifing the correct len
	if (stat_file.st_size != (36 + header.len_video_file + header.len_audio_file))
	{
		header.error = FILE_CORRUPT;
		return header;
	}
	header.error = FILE_OK;
	return header;
}

void audio_video_extract(char* filename_audio, char* filename_video, DpgHeader* header)
{
	FILE* audio_file = NULL;
	FILE* video_file = NULL;
	int i = 0;

	//step 1 : open file
	if (filename_audio == NULL || filename_video == NULL)
	{
		header->error = BAD_ARGS;
		return;
	}
	audio_file = fopen(filename_audio, "w");
	video_file = fopen(filename_video, "w");
	if (!audio_file || !video_file) 
	{
		header->error = CANT_OPEN_FILE;
		return;
	}
	
	//step 2 : copy audio file
	fseek(header->file, SEEK_SET, header->bigin_audio_file);
	for (i = 0; i != header->len_audio_file; i++)
	{
		fputc(fgetc(header->file), audio_file);
	}
	//step 3 : copy video file
	fseek(header->file, SEEK_SET, header->bigin_video_file);
	for (i = 0; i != header->len_video_file; i++)
	{
		fputc(fgetc(header->file), video_file);
	}
	//step 4 : close files
	fclose(video_file);
	fclose(audio_file);

	//step 5 : file ok : copy name of file on struct
	header->filename_audio = safecopy(filename_audio);
	header->filename_video = safecopy(filename_video);

	if (header->filename_audio == NULL || header->filename_video == NULL)
	{
		header->error = MALLOC_FALL;
	}
}
